Custom Dropdown in Selenium WebDriver
A Custom Dropdown is a dropdown component created using HTML elements such as <div>, <span>, <li>, <button>, or other elements instead of the standard HTML <select> element. Custom dropdowns are widely used in modern web applications because they provide better styling, animations, search functionality, icons, multi-selection, and dynamic behavior.
In Selenium WebDriver automation, handling a custom dropdown is different from handling a standard HTML dropdown. The Selenium Select class should generally be used only when the dropdown is represented by an actual HTML <select> element. For custom dropdowns, testers normally locate the dropdown trigger and option elements and interact with them using Selenium locators, waits, keyboard actions, JavaScript when necessary, and other WebDriver techniques.
Course Resources: Selenium Training Course | Register for Course Demo
1. What is a Custom Dropdown?
A Custom Dropdown is a user-interface component that displays a list of selectable values when a user clicks, taps, hovers over, or otherwise interacts with a particular element. Unlike a standard HTML dropdown, it is usually implemented with generic HTML elements and JavaScript.
<div class="custom-dropdown">
<button class="dropdown-button">Select Country</button>
<div class="dropdown-options">
<div class="option">India</div>
<div class="option">USA</div>
<div class="option">Canada</div>
</div>
</div>
Here, the dropdown is not a <select> element. Therefore, Selenium's Select class should not be used for this component.
2. Standard Dropdown vs Custom Dropdown
| Feature | Standard Dropdown | Custom Dropdown |
| HTML element | <select> | Usually <div>, <button>, <li>, etc. |
| Selenium Select class | Supported | Normally not applicable |
| Options | <option> | Can be any HTML element |
| Styling | Browser-dependent | Highly customizable |
| Search | Limited | Can easily support search |
| Icons | Limited | Commonly supported |
| Multi-select | Supported in some implementations | Commonly customized |
| Automation | Usually simpler | Requires element-level interaction |
3. Why Custom Dropdowns Are Used?
- Better visual design
- Custom animations
- Searchable options
- Icons and images inside options
- Multi-select functionality
- Dynamic loading of options
- Mobile-friendly interactions
- Integration with JavaScript frameworks
- Custom keyboard navigation
- Improved user experience
4. How a Custom Dropdown Works
A typical custom dropdown follows this flow:
User clicks dropdown
↓
Dropdown menu becomes visible
↓
Options are rendered/displayed
↓
User selects an option
↓
Selected value appears in dropdown
↓
Dropdown closes or remains open
5. Identifying a Custom Dropdown
Before writing Selenium code, inspect the dropdown in the browser's developer tools.
Check whether the element is implemented using <select> or another HTML element.
<button id="countryDropdown">Select Country</button>
<div class="options">
<div class="country">India</div>
<div class="country">USA</div>
</div>
Since this example uses a button and div elements, it is a custom dropdown.
6. Basic Selenium Setup
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class CustomDropdownExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://example.com");
driver.quit();
}
}
7. Locate the Dropdown Trigger
The first step is to locate the element that opens the dropdown.
WebElement dropdown = driver.findElement(
By.id("countryDropdown")
);
Click the trigger:
dropdown.click();
8. Locate an Option by Visible Text
After opening the dropdown, an option can often be located using its visible text.
WebElement india = driver.findElement(
By.xpath("//div[normalize-space()='India']")
);
india.click();
9. Complete Custom Dropdown Example
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://example.com");
driver.findElement(By.id("countryDropdown")).click();
driver.findElement(
By.xpath("//div[normalize-space()='India']")
).click();
driver.quit();
10. Using CSS Selector
CSS selectors can be useful when custom dropdowns have meaningful classes or attributes.
driver.findElement(
By.cssSelector(".country-dropdown")
).click();
driver.findElement(
By.cssSelector(".country-option[data-value='india']")
).click();
11. Using XPath
XPath is especially useful when the option text or relationship between elements is important.
driver.findElement(
By.xpath("//button[@id='countryDropdown']")
).click();
driver.findElement(
By.xpath("//div[contains(@class,'option') and normalize-space()='India']")
).click();
12. Using normalize-space()
Custom dropdown options may contain extra spaces or formatted text. normalize-space() helps create a more reliable XPath.
driver.findElement(
By.xpath("//div[normalize-space()='India']")
).click();
13. Why normalize-space() Is Useful
Consider this HTML:
<div class="option">
India
</div>
A normalized XPath can handle unnecessary whitespace:
By.xpath("//div[normalize-space()='India']")
14. Selecting an Option Using a Data Attribute
Modern applications frequently provide custom attributes such as data-value.
<div class="option" data-value="india">India</div>
<div class="option" data-value="usa">USA</div>
Selenium:
driver.findElement(
By.cssSelector(".option[data-value='india']")
).click();
15. Selecting by ID
driver.findElement(By.id("countryDropdown")).click();
driver.findElement(By.id("indiaOption")).click();
ID-based locators are generally straightforward when IDs are unique and stable.
16. Selecting by Class Name
driver.findElement(
By.className("dropdown-trigger")
).click();
Class names should be used carefully because multiple elements may share the same class.
17. Finding All Dropdown Options
Sometimes automation requires retrieving every available option.
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
Import:
import java.util.List;
18. Print All Dropdown Options
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
for (WebElement option : options) {
System.out.println(option.getText());
}
19. Select an Option Using a Loop
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
for (WebElement option : options) {
if (option.getText().trim().equals("India")) {
option.click();
break;
}
}
20. Selecting an Option by Index
If the position of an option is stable, it can be selected by index.
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
options.get(2).click();
Index-based selection can become unreliable when the order of options changes, so text or stable attributes are generally preferable.
21. Explicit Wait for Custom Dropdown
Many custom dropdowns are dynamic. The menu or options may not immediately appear after clicking the trigger. Explicit waits can synchronize the test with the application.
import java.time.Duration;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement dropdown = wait.until(
ExpectedConditions.elementToBeClickable(
By.id("countryDropdown")
)
);
dropdown.click();
22. Wait for an Option to Become Visible
WebElement india = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//div[normalize-space()='India']")
)
);
india.click();
23. Wait for an Option to Become Clickable
WebElement india = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
);
india.click();
24. Why Explicit Wait Is Important
- Prevents unnecessary timing failures
- Handles dynamically rendered elements
- Improves test stability
- Reduces dependence on fixed delays
- Works well with AJAX-based interfaces
25. Avoid Thread.sleep()
Although Thread.sleep() can temporarily solve synchronization problems, it is usually less efficient than condition-based waits.
Thread.sleep(3000);
A better approach is:
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".dropdown-option")
)
);
26. Dynamic Custom Dropdown
Some dropdowns load options only after the user clicks the dropdown.
User clicks dropdown
↓
JavaScript request starts
↓
Server/API returns data
↓
Options are rendered
↓
Selenium locates option
↓
Option is clicked
For such dropdowns, Selenium should wait for the option instead of immediately searching for it.
27. AJAX-Based Custom Dropdown
driver.findElement(
By.id("countryDropdown")
).click();
WebElement india = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[contains(@class,'option') and normalize-space()='India']")
)
);
india.click();
28. Handling StaleElementReferenceException
A custom dropdown may refresh its options after opening. Previously located WebElements can then become stale.
WebElement option = driver.findElement(
By.xpath("//div[normalize-space()='India']")
);
driver.findElement(By.id("countryDropdown")).click();
option.click();
If the DOM was refreshed between locating and clicking, the stored element may no longer represent the current DOM element.
A better approach is to locate the element after the dropdown has opened:
driver.findElement(By.id("countryDropdown")).click();
WebElement option = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
);
option.click();
29. Handling TimeoutException
A timeout can occur when Selenium waits for an element that does not become available within the specified period.
Possible causes include:
- Incorrect locator
- Dropdown did not open
- Option is loaded later
- Wrong frame
- Application error
- Option text changed
30. Handling NoSuchElementException
This exception usually indicates that Selenium could not locate the requested element.
Check:
- Locator correctness
- Element visibility
- Page state
- Iframe context
- Dynamic rendering
31. Handling ElementClickInterceptedException
This exception can occur when another element, overlay, animation, or popup prevents Selenium from clicking the dropdown option.
Possible solutions:
- Wait for the overlay to disappear
- Scroll the element into view
- Wait for the element to become clickable
- Check whether another popup is covering the element
32. Scrolling to a Custom Dropdown
WebElement dropdown = driver.findElement(
By.id("countryDropdown")
);
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView({block:'center'});",
dropdown
);
Required import:
import org.openqa.selenium.JavascriptExecutor;
33. JavaScript Click
JavaScript can sometimes be used as a fallback when normal Selenium clicking is blocked by application behavior.
WebElement option = driver.findElement(
By.xpath("//div[normalize-space()='India']")
);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(
"arguments[0].click();",
option
);
JavaScript click should generally be considered a fallback rather than the first choice because it may bypass aspects of normal user interaction.
34. Hover-Based Custom Dropdown
Some dropdowns appear when the mouse pointer is moved over a menu item.
import org.openqa.selenium.interactions.Actions;
Actions actions = new Actions(driver);
WebElement menu = driver.findElement(
By.id("productsMenu")
);
actions.moveToElement(menu).perform();
35. Select Option After Hover
actions.moveToElement(menu).perform();
WebElement option = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='Laptops']")
)
);
option.click();
36. Keyboard-Based Custom Dropdown
Some custom dropdowns support keyboard navigation.
WebElement dropdown = driver.findElement(
By.id("countryDropdown")
);
dropdown.click();
dropdown.sendKeys(Keys.ARROW_DOWN);
dropdown.sendKeys(Keys.ENTER);
Required import:
import org.openqa.selenium.Keys;
37. Selecting Multiple Options
Some custom dropdowns allow users to select multiple values.
driver.findElement(
By.id("skillsDropdown")
).click();
driver.findElement(
By.xpath("//div[normalize-space()='Java']")
).click();
driver.findElement(
By.xpath("//div[normalize-space()='Selenium']")
).click();
driver.findElement(
By.xpath("//div[normalize-space()='SQL']")
).click();
38. Searchable Custom Dropdown
Searchable dropdowns contain an input field that filters available options.
driver.findElement(
By.id("countryDropdown")
).click();
WebElement search = driver.findElement(
By.cssSelector(".dropdown-search")
);
search.sendKeys("India");
Then wait for the filtered option:
WebElement india = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[contains(@class,'option') and normalize-space()='India']")
)
);
india.click();
39. Custom Dropdown with Input Field
<div class="dropdown">
<input id="countrySearch" placeholder="Search country">
<div class="option">India</div>
<div class="option">USA</div>
</div>
Selenium:
driver.findElement(
By.id("countrySearch")
).sendKeys("India");
driver.findElement(
By.xpath("//div[normalize-space()='India']")
).click();
40. Dynamic IDs
Some applications generate IDs dynamically.
<div id="option-982341">India</div>
Instead of relying on the changing numeric portion, use stable attributes or text.
driver.findElement(
By.xpath("//div[starts-with(@id,'option-') and normalize-space()='India']")
).click();
41. Using contains() for Dynamic Attributes
driver.findElement(
By.xpath("//div[contains(@id,'option-') and normalize-space()='India']")
).click();
42. Using ARIA Attributes
Accessible custom dropdowns may contain attributes such as role and aria-expanded.
<div role="combobox"
aria-expanded="false"
id="countryDropdown">
Select Country
</div>
Selenium:
driver.findElement(
By.cssSelector("[role='combobox']")
).click();
43. Checking aria-expanded
The aria-expanded attribute can help determine whether the dropdown is open.
WebElement dropdown = driver.findElement(
By.id("countryDropdown")
);
dropdown.click();
String expanded = dropdown.getAttribute("aria-expanded");
System.out.println(expanded);
44. Validating Dropdown Is Open
String expanded = dropdown.getAttribute("aria-expanded");
if ("true".equals(expanded)) {
System.out.println("Dropdown is open");
}
45. Validating Selected Value
After selecting an option, automation should verify that the expected value is displayed.
WebElement dropdown = driver.findElement(
By.id("countryDropdown")
);
String selectedValue = dropdown.getText();
if (selectedValue.trim().equals("India")) {
System.out.println("Correct country selected");
}
46. Assert Selected Value Using TestNG
import static org.testng.Assert.assertEquals;
String actual = driver.findElement(
By.id("countryDropdown")
).getText().trim();
assertEquals(actual, "India");
47. Custom Dropdown Inside a Form
driver.findElement(By.id("countryDropdown")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
).click();
driver.findElement(By.id("firstName")).sendKeys("John");
driver.findElement(By.id("submit")).click();
48. Custom Dropdown in an E-Commerce Application
E-commerce applications commonly use custom dropdowns for:
- Product categories
- Product sizes
- Product colors
- Sort options
- Price filters
- Quantity selection
- Shipping locations
driver.findElement(
By.id("sortDropdown")
).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='Price: Low to High']")
)
).click();
49. Custom Dropdown in a Registration Form
driver.findElement(
By.id("countryDropdown")
).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
).click();
driver.findElement(
By.id("stateDropdown")
).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='Maharashtra']")
)
).click();
50. Dependent Custom Dropdowns
In some forms, the second dropdown depends on the first dropdown.
Select Country
↓
Country selected
↓
States loaded
↓
Select State
↓
Cities loaded
↓
Select City
Automation should wait for the dependent options to appear after each selection.
51. Handling Country-State Dropdown
driver.findElement(By.id("country")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
).click();
driver.findElement(By.id("state")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='Maharashtra']")
)
).click();
52. Custom Dropdown Inside an Iframe
If the dropdown exists inside an iframe, Selenium must switch to the iframe before interacting with the dropdown.
WebElement frame = driver.findElement(
By.cssSelector("iframe.payment-frame")
);
driver.switchTo().frame(frame);
driver.findElement(
By.id("countryDropdown")
).click();
driver.findElement(
By.xpath("//div[normalize-space()='India']")
).click();
driver.switchTo().defaultContent();
53. Handling Nested Dropdown Elements
Sometimes the visible text is inside a nested element.
<div class="option">
<span class="country-name">India</span>
</div>
XPath:
driver.findElement(
By.xpath("//div[contains(@class,'option')]//span[normalize-space()='India']")
).click();
54. Dropdown Option With Icon
<div class="option">
<img src="india.png">
<span>India</span>
</div>
The text-based XPath can target the visible country name:
driver.findElement(
By.xpath("//div[contains(@class,'option')]//span[normalize-space()='India']")
).click();
55. Shadow DOM Custom Dropdown
Modern web applications may use Shadow DOM. Normal Selenium locators may not always reach elements inside a shadow root in the same way as ordinary DOM elements.
WebElement host = driver.findElement(
By.cssSelector("custom-dropdown")
);
SearchContext shadowRoot = host.getShadowRoot();
WebElement button = shadowRoot.findElement(
By.cssSelector("button")
);
button.click();
56. Shadow DOM Option Selection
WebElement host = driver.findElement(
By.cssSelector("custom-dropdown")
);
SearchContext shadowRoot = host.getShadowRoot();
shadowRoot.findElement(
By.cssSelector(".option[data-value='india']")
).click();
57. Page Object Model for Custom Dropdown
Custom dropdown interactions should be placed in Page Object classes when the same component is used repeatedly.
public class RegistrationPage {
private WebDriver driver;
private By countryDropdown =
By.id("countryDropdown");
private By indiaOption =
By.xpath("//div[normalize-space()='India']");
public RegistrationPage(WebDriver driver) {
this.driver = driver;
}
public void selectIndia() {
driver.findElement(countryDropdown).click();
driver.findElement(indiaOption).click();
}
}
58. Reusable Custom Dropdown Method
A generic utility method can reduce duplicate code.
public void selectCustomDropdown(
By dropdownLocator,
By optionLocator) {
driver.findElement(dropdownLocator).click();
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.elementToBeClickable(optionLocator)
).click();
}
59. Using the Reusable Method
selectCustomDropdown(
By.id("countryDropdown"),
By.xpath("//div[normalize-space()='India']")
);
60. Generic Method Using Visible Text
public void selectCustomDropdown(
By dropdownLocator,
String optionText) {
driver.findElement(dropdownLocator).click();
By optionLocator = By.xpath(
"//*[normalize-space()=" +
"'" + optionText + "']"
);
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.elementToBeClickable(optionLocator)
).click();
}
61. Better Generic XPath Construction
When option text contains apostrophes, constructing XPath by direct string concatenation can become problematic. In production frameworks, XPath string escaping or stable attributes should be preferred.
For predictable option values, data attributes are often easier to automate.
By option = By.cssSelector(
".dropdown-option[data-value='india']"
);
62. Locator Priority for Custom Dropdowns
A practical locator preference is:
- Stable unique ID
- Stable custom attribute
- Stable data attribute
- Reliable CSS selector
- Reliable XPath
- Visible text when appropriate
- Index as a last resort
63. Avoid Fragile XPath
Avoid overly dependent XPath expressions based on generated class names or deep DOM structures.
Fragile example:
/html/body/div[2]/div[3]/div[1]/div[4]
Prefer a meaningful locator:
//div[@data-value='india']
64. Handling Hidden Options
Some dropdown options exist in the DOM but are hidden until the dropdown opens. Selenium should normally interact with the visible, interactable state.
driver.findElement(
By.id("countryDropdown")
).click();
WebElement option = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//div[normalize-space()='India']")
)
);
option.click();
65. Dropdown With Animation
Animated dropdowns can cause click timing problems because the option may exist but not yet be ready for interaction.
WebElement option = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
);
option.click();
66. Handling Overlay
Dropdowns may open an overlay behind or around the option list. If the overlay blocks the interaction, wait for the correct element state or handle the overlay according to the application's behavior.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-overlay")
)
);
67. Handling Loading Indicators
driver.findElement(By.id("countryDropdown")).click();
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-spinner")
)
);
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
).click();
68. Verify Dropdown Options
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
System.out.println(
"Total options: " + options.size()
);
69. Verify Expected Option Exists
boolean found = false;
List<WebElement> options = driver.findElements(
By.cssSelector(".dropdown-option")
);
for (WebElement option : options) {
if (option.getText().trim().equals("India")) {
found = true;
break;
}
}
System.out.println("India available: " + found);
70. Verify Dropdown Is Closed
After selecting an option, some applications close the dropdown automatically.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".dropdown-options")
)
);
71. Verify Dropdown Is Open
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".dropdown-options")
)
);
72. Handling Table Row Dropdowns
Applications may contain several dropdowns inside different table rows. The automation should first identify the correct row and then interact with its dropdown.
WebElement row = driver.findElement(
By.xpath("//tr[td[normalize-space()='John']]")
);
row.findElement(
By.cssSelector(".status-dropdown")
).click();
row.findElement(
By.xpath(".//div[normalize-space()='Active']")
).click();
73. Why Relative XPath Is Useful in Tables
Using . in the XPath keeps the search within the selected row.
row.findElement(
By.xpath(".//div[normalize-space()='Active']")
).click();
This helps prevent Selenium from accidentally selecting an option belonging to another row.
74. Custom Dropdown in a Modal
WebElement modal = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".modal")
)
);
modal.findElement(
By.cssSelector(".country-dropdown")
).click();
modal.findElement(
By.xpath(".//div[normalize-space()='India']")
).click();
75. Custom Dropdown With Checkbox Options
Some multi-select dropdowns contain checkboxes.
<div class="option">
<input type="checkbox" value="java">
<span>Java</span>
</div>
Selenium:
WebElement javaOption = driver.findElement(
By.xpath("//div[contains(@class,'option')][.//span[normalize-space()='Java']]")
);
javaOption.click();
76. Selecting Multiple Checkbox Options
driver.findElement(
By.xpath("//div[contains(@class,'option')][.//span[normalize-space()='Java']]")
).click();
driver.findElement(
By.xpath("//div[contains(@class,'option')][.//span[normalize-space()='Python']]")
).click();
driver.findElement(
By.xpath("//div[contains(@class,'option')][.//span[normalize-space()='SQL']]")
).click();
77. Handling Selected State
Custom dropdowns may indicate selection through attributes or CSS classes.
<div class="option selected">
India
</div>
Verify using class:
String classes = option.getAttribute("class");
if (classes.contains("selected")) {
System.out.println("Option selected");
}
78. Checking aria-selected
String selected = option.getAttribute(
"aria-selected"
);
if ("true".equals(selected)) {
System.out.println("Option is selected");
}
79. Handling Dropdowns With Long Option Lists
Some custom dropdowns contain many options and use internal scrolling.
WebElement optionList = driver.findElement(
By.cssSelector(".dropdown-options")
);
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollTop = arguments[0].scrollHeight;",
optionList
);
80. Scroll an Option Into View
WebElement option = driver.findElement(
By.xpath("//div[normalize-space()='India']")
);
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView({block:'center'});",
option
);
option.click();
81. Custom Dropdown With Virtualized Options
Large applications may render only currently visible options. In such cases, an option may not exist in the DOM until the list is scrolled or searched.
For these dropdowns, searching by text or using the component's built-in search mechanism can be more reliable than expecting every option to be present at once.
82. Custom Dropdown With React or Angular
Modern JavaScript frameworks commonly generate custom dropdowns using dynamically rendered elements. The DOM can change after every interaction.
Recommended approach:
- Use stable attributes where available
- Wait for dynamic elements
- Locate elements after state changes
- Avoid storing WebElements longer than necessary
- Verify the final selected state
83. React-Style Dropdown Example
driver.findElement(
By.cssSelector("[role='combobox']")
).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.cssSelector("[role='option'][data-value='india']")
)
).click();
84. Role-Based Locators
ARIA roles can provide meaningful selectors when the application implements accessibility correctly.
By.cssSelector("[role='combobox']")
By.cssSelector("[role='listbox']")
By.cssSelector("[role='option']")
85. Finding a Specific Role Option
driver.findElement(
By.xpath("//*[@role='option' and normalize-space()='India']")
).click();
86. Custom Dropdown Test Scenario
Scenario: Verify that a user can select India from a Country custom dropdown.
- Open the application.
- Navigate to the required form.
- Click the Country dropdown.
- Wait for the options.
- Select India.
- Verify that India is displayed as the selected value.
87. Test Case Example
| Step | Action | Expected Result |
| 1 | Open page | Page loads successfully |
| 2 | Click Country dropdown | Options become visible |
| 3 | Select India | India becomes selected |
| 4 | Verify selected value | India is displayed |
| 5 | Submit form | Form is submitted successfully |
88. Complete TestNG Example
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class CustomDropdownTest {
private WebDriver driver;
private WebDriverWait wait;
@BeforeMethod
public void setUp() {
driver = new ChromeDriver();
driver.manage().window().maximize();
wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
driver.get("https://example.com");
}
@Test
public void selectCountry() {
driver.findElement(
By.id("countryDropdown")
).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
).click();
String selectedValue = driver.findElement(
By.id("countryDropdown")
).getText().trim();
Assert.assertEquals(
selectedValue,
"India"
);
}
@AfterMethod
public void tearDown() {
driver.quit();
}
}
89. Common Mistakes in Custom Dropdown Automation
- Using
Select for a non-<select> element
- Clicking the option before opening the dropdown
- Using fixed sleeps everywhere
- Using unstable generated classes
- Ignoring dynamic rendering
- Not waiting for options
- Using an incorrect XPath
- Ignoring iframe context
- Ignoring Shadow DOM
- Not validating the selected value
- Using index-based selection unnecessarily
- Keeping stale WebElements after DOM updates
90. Best Practices
- Inspect the HTML before writing automation.
- First determine whether the component is standard or custom.
- Use
Select only for genuine HTML <select> elements.
- Prefer stable IDs and data attributes.
- Use explicit waits for dynamic options.
- Locate dynamic options after opening the dropdown.
- Use visible text carefully.
- Prefer meaningful CSS selectors or XPath.
- Avoid absolute XPath.
- Verify the final selected state.
- Keep dropdown interaction logic reusable.
- Use Page Object Model for maintainable frameworks.
91. Custom Dropdown Automation Flow
Start Test
↓
Open Web Page
↓
Locate Dropdown Trigger
↓
Click Dropdown
↓
Wait for Options
↓
Locate Required Option
↓
Click Option
↓
Verify Selected Value
↓
Continue Test
↓
End Test
92. Standard Dropdown vs Custom Dropdown Automation
| Operation | Standard Dropdown | Custom Dropdown |
| Open dropdown | Select or normal interaction | Click/hover/keyboard |
| Select by text | SelectByVisibleText | Locate option and click |
| Select by value | SelectByValue | Use data attribute or custom locator |
| Select by index | SelectByIndex | Find list and use index if appropriate |
| Dynamic options | May require waits | Frequently requires waits |
| Search | Browser/component dependent | Often implemented manually |
93. When Should You Use Select Class?
Use Selenium's Select class when the HTML structure contains a genuine <select> element.
<select id="country">
<option value="india">India</option>
<option value="usa">USA</option>
</select>
Select select = new Select(
driver.findElement(By.id("country"))
);
select.selectByVisibleText("India");
94. When Should You Not Use Select Class?
Do not use Select for HTML such as:
<div class="dropdown">
<div class="option">India</div>
</div>
Instead, locate and interact with the custom elements.
95. Custom Dropdown Utility Class
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class DropdownUtils {
private WebDriver driver;
private WebDriverWait wait;
public DropdownUtils(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
}
public void select(
By dropdown,
By option) {
wait.until(
ExpectedConditions.elementToBeClickable(dropdown)
).click();
wait.until(
ExpectedConditions.elementToBeClickable(option)
).click();
}
}
96. Using Dropdown Utility
DropdownUtils dropdownUtils =
new DropdownUtils(driver);
dropdownUtils.select(
By.id("countryDropdown"),
By.xpath("//div[normalize-space()='India']")
);
97. Negative Testing for Custom Dropdowns
Custom dropdown testing should also verify invalid or unexpected situations.
- Dropdown cannot be opened
- Required option is missing
- Options fail to load
- Search returns no results
- Duplicate options appear
- Selected value is not displayed
- Dropdown closes unexpectedly
- Loading spinner never disappears
98. No Results Scenario
driver.findElement(
By.id("countryDropdown")
).click();
driver.findElement(
By.id("countrySearch")
).sendKeys("XYZ");
WebElement noResults = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".no-results")
)
);
System.out.println(noResults.getText());
99. Duplicate Option Testing
If the same option text can appear multiple times, avoid selecting the first matching element without confirming the correct context.
List<WebElement> indiaOptions = driver.findElements(
By.xpath("//div[normalize-space()='India']")
);
System.out.println(
"Matching options: " + indiaOptions.size()
);
100. Dropdown Testing Checklist
- Verify dropdown is visible.
- Verify dropdown is clickable.
- Verify dropdown opens correctly.
- Verify all expected options are displayed.
- Verify option selection.
- Verify selected value.
- Verify dropdown closes correctly.
- Verify keyboard navigation if supported.
- Verify search functionality if supported.
- Verify multi-selection if supported.
- Verify dependent dropdown behavior.
- Verify loading behavior.
- Verify error and no-result behavior.
101. Real-World Example: Job Application Form
A job application form may contain custom dropdowns for:
- Country
- State
- City
- Experience
- Education
- Employment Type
- Notice Period
The automation should select each value and verify that the corresponding value is displayed before submitting the form.
102. Real-World Example: Travel Booking
Travel websites frequently use custom controls for:
- Departure city
- Destination city
- Passenger count
- Travel class
- Nationality
- Currency
These components can include search, dynamic loading, keyboard navigation, and nested elements.
103. Real-World Example: Banking Application
A banking application may use custom dropdowns for:
- Account type
- Transaction type
- Country
- Currency
- Payment method
Automation should verify both selection and the resulting application state.
104. Mini Project: Automate a Registration Form
Project Objective: Automate a registration form containing custom Country and State dropdowns.
Steps:
- Launch Chrome.
- Open registration page.
- Enter user details.
- Open Country custom dropdown.
- Select India.
- Wait for State options.
- Open State dropdown.
- Select Maharashtra.
- Verify both selections.
- Submit the form.
- Verify successful registration.
105. Interview Question: What Is a Custom Dropdown?
A custom dropdown is a dropdown component implemented using elements other than the standard HTML <select> element. It may use buttons, divs, spans, list items, JavaScript, ARIA attributes, and dynamic rendering.
106. Interview Question: How Do You Handle a Custom Dropdown in Selenium?
First inspect the HTML and identify the dropdown trigger and option elements. Click the trigger, wait for the options if necessary, locate the required option using a stable locator, click it, and verify the selected value.
107. Interview Question: Can Select Class Handle Custom Dropdowns?
Normally, no. Selenium's Select class is designed for HTML <select> elements. A custom dropdown implemented with divs, buttons, list items, or other elements should be handled using normal WebDriver interactions and appropriate synchronization.
108. Interview Question: How Do You Handle a Dynamic Custom Dropdown?
Use explicit waits to wait for the dropdown options to become visible or clickable. Locate the option after the dropdown has opened and avoid storing elements that may become stale after DOM updates.
109. Interview Question: How Do You Select an Option by Text?
driver.findElement(
By.xpath("//div[normalize-space()='India']")
).click();
110. Interview Question: How Do You Handle a Searchable Dropdown?
Click the dropdown, locate its search field, enter the required text, wait for the filtered option, select it, and verify the selected value.
111. Interview Question: How Do You Handle Stale Elements?
When a dropdown refreshes its DOM, previously located elements may become stale. Re-locate the element after the DOM update and use an explicit wait for the current element.
112. Interview Question: How Do You Handle a Dropdown Inside an Iframe?
Switch to the appropriate iframe first, interact with the dropdown, and then switch back to the main document using driver.switchTo().defaultContent().
113. Interview Question: What Locators Are Useful for Custom Dropdowns?
Useful locators include ID, name, CSS selector, XPath, stable data attributes, ARIA attributes, role attributes, and reliable visible text.
114. Interview Question: Why Are Explicit Waits Important?
Custom dropdowns are often dynamically rendered. Explicit waits allow the test to synchronize with conditions such as visibility or clickability instead of relying on arbitrary fixed delays.
115. Interview Question: How Do You Verify a Dropdown Selection?
Read the displayed selected value, selected CSS class, aria-selected attribute, or another application-specific state and compare it with the expected value.
116. Quick Revision
- Custom dropdowns are not necessarily based on
<select>.
- Inspect the DOM before automating.
- Do not automatically use the
Select class.
- Click the dropdown trigger first.
- Wait for dynamic options.
- Locate the required option.
- Click the option.
- Verify the selected value.
- Use stable locators.
- Handle AJAX and dynamic rendering.
- Handle iframes when required.
- Handle Shadow DOM when required.
- Use Page Object Model for maintainability.
117. Practical Custom Dropdown Template
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
driver.findElement(
By.id("dropdown")
).click();
WebElement option = wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//div[normalize-space()='India']")
)
);
option.click();
String selected = driver.findElement(
By.id("dropdown")
).getText().trim();
Assert.assertEquals(selected, "India");
118. Best Practice Summary
| Practice | Recommendation |
| Identify type | Check whether it is native or custom |
| Locators | Prefer stable attributes |
| Synchronization | Use explicit waits |
| Dynamic DOM | Locate elements after state changes |
| Selection | Prefer text or stable attributes |
| Validation | Verify selected state |
| Framework | Use Page Object Model |
| Fallback | Use JavaScript only when appropriate |
| Maintainability | Use reusable dropdown utilities |
119. Course Resource
To learn Selenium WebDriver, automation frameworks, locators, waits, browser automation, Page Object Model, and related testing concepts, explore the Selenium Training Course.
For course information or to schedule a demo, visit Register for Course Demo.
120. Conclusion
Custom Dropdown handling is an important Selenium WebDriver skill because modern web applications frequently use dropdown components built with divs, buttons, spans, list items, JavaScript, ARIA roles, and dynamically generated elements instead of traditional HTML <select> elements. The key to reliable automation is to understand the DOM structure, identify the dropdown trigger and option elements, use stable locators, synchronize dynamic behavior with explicit waits, and verify the selected state.
For maintainable automation frameworks, custom dropdown interactions should be implemented through reusable methods and Page Object Model classes. Handling dynamic options, searchable dropdowns, multi-select components, dependent dropdowns, iframes, Shadow DOM, overlays, animations, and stale elements correctly helps create stable and scalable Selenium test automation.
Selenium Training Course | Register for Course Demo